package com.example.week14;

import com.example.week14.dao.impl.StudentDaoImpl;
import com.example.week14.entity.Student;
import com.example.week14.util.DruidUtil;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.*;


public class StudentView {
    @FXML
    private Pagination pageTable;//分页组件
    private int itemsPerPage = 10;//每页显示的数据条数
    // 使用FXML注解将FXML文件中的TableView控件与Java代码中的studentTableView字段进行关联
    @FXML
    private TableView<Student> studentTableView;
    // 定义与TableView中的列对应的TableColumn字段，并使用FXML注解进行关联
    @FXML
    private TableColumn<Student, String> age;
    @FXML
    private TableColumn<Student, String> name;
    @FXML
    private TableColumn<Student, String> photo;
    @FXML
    private TableColumn<Student, String> sex;
    @FXML
    private TableColumn<Student, String> sno;
    @FXML
    private TableColumn<Student, String> tel;

    // 新增输入框
    @FXML
    private TextField inputStudentId;
    @FXML
    private TextField inputStudentName;
    @FXML
    private TextField inputStudentAge;
    @FXML
    private ToggleButton maleToggleButton;
    @FXML
    private ToggleButton femaleToggleButton;
    @FXML
    private TextField inputStudentTel;

    //新增按钮
    @FXML
    private Button addButton;
    @FXML
    private Button queryButton;
    @FXML
    private Label resultCountLabel;

    @FXML
    private void initialize() {//页面初始化
        // 初始化分页控件
        initPagination();
        // 加载学生数据，默认加载第一页
        loadPageData(0);
        // 设置TableView的多选模式
        studentTableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
    }

    //初始化分页控件，设置总页数，并添加页码变化监听器。
    private void initPagination() {
        // 设置分页控件的页数
        pageTable.setPageCount(calculatePageCount());
        // 监听页码变化事件，当页码变化时刷新表格数据
        pageTable.currentPageIndexProperty().addListener((observable
                , oldValue, newValue) -> {
            // 根据新的页码加载数据
            loadPageData(newValue.intValue());
        });
    }

    //计算总页数，基于总记录数和每页显示的条数。
    private int calculatePageCount() {
        // 获取总记录数
        try (Connection connection = DruidUtil.getConnection()) {
            StudentDaoImpl studentDao = new StudentDaoImpl(connection);
            // 计算总页数，并向上取整
            return (int) Math.ceil((double) studentDao.getTotalRecords() / itemsPerPage);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    //加载指定页码的数据到 TableView 中。
    private void loadPageData(int pageIndex) {
        try (Connection connection = DruidUtil.getConnection()) {
            StudentDaoImpl studentDao = new StudentDaoImpl(connection);
            // 获取每页数据
            List<Student> pageData = studentDao.selectByPage(pageIndex + 1, itemsPerPage);
            // 将数据加载到 TableView 中
            updateTableView(pageData);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //更新TableView中的数据
    private void updateTableView(List<Student> students) {
        // 传入List集合，更新TableView
        studentTableView.getItems().setAll(students);
        // 为每列设置单元格值工厂，以从学生对象中获取属性值显示。
        sno.setCellValueFactory(new PropertyValueFactory<>("sno"));
        name.setCellValueFactory(new PropertyValueFactory<>("name"));
        age.setCellValueFactory(new PropertyValueFactory<>("age"));
        sex.setCellValueFactory(new PropertyValueFactory<>("sex"));
        tel.setCellValueFactory(new PropertyValueFactory<>("tel"));
        photo.setCellValueFactory(new PropertyValueFactory<>("photo"));
        // 使用Lambda表达式为表格列设置自定义的单元格工厂
        photo.setCellFactory(column -> createPhotoCell());
    }

    //创建用于显示学生照片的自定义表格单元格
    private TableCell<Student, String> createPhotoCell() {
        return new TableCell<Student, String>() {
            // 在单元格初始化或更新时调用
            // photoPath 表示当前单元格的图片路径，empty 表示单元格是否为空。
            @Override
            protected void updateItem(String photoPath,boolean empty) {
                super.updateItem(photoPath, empty);
                // 如果单元格为空或者 photoPath 为空，清空图形和文本
                if (empty || photoPath == null) {
                    setGraphic(null);
                    setText(null);
                    return;
                }
                // 调用 createImageBox 方法创建水平盒子并设置图片和大小
                setGraphic(createImageBox(photoPath));
            }
        };
    }

    // 创建水平盒子并设置图片和大小的方法
    private HBox createImageBox(String photoPath) {
        HBox box = new HBox();
        box.setAlignment(Pos.CENTER);
        // 根据路径加载图片，确保路径正确
        Image image = new Image(getClass().getResourceAsStream("/com/example/week14/photo/" + photoPath));
        // 创建ImageView并设置大小
        ImageView imageView = new ImageView(image);
        imageView.setFitWidth(48);
        imageView.setFitHeight(48);
        // 将ImageView添加到水平盒子中
        box.getChildren().add(imageView);
        return box;
    }

    // 删除选定的学生信息的方法
    private void deleteSelectedStudents(List<Student>
                                                selectedStudents) throws Exception {
        try (Connection connection = DruidUtil.getConnection()) {
            // 创建学生数据访问对象
            StudentDaoImpl studentDao = new
                    StudentDaoImpl(connection);
            // 遍历选定的学生，逐个删除
            for (Student student : selectedStudents) {
                studentDao.deleteByPrimaryKey(student.getSno());
            }
        }
    }

    // 刷新表格数据
    private void refreshTableView() {
        // 获取当前页码
        int currentPageIndex = pageTable.getCurrentPageIndex();
        // 获取新的总页数
        int newTotalPages = calculatePageCount();
        // 更新分页控件的页数
        pageTable.setPageCount(newTotalPages);
        // 重新加载当前页数据
        loadPageData(currentPageIndex);
        // 如果当前页为空且不是第一页，将页码减一，重新加载上一页数据
        if (studentTableView.getItems().isEmpty() &&
                currentPageIndex > 0) {
            loadPageData(currentPageIndex - 1);
            pageTable.setCurrentPageIndex(currentPageIndex - 1);//设置当前页码
        }
    }

    //数据表格右键删除菜单事件
    @FXML
    private void btnDel(ActionEvent actionEvent) {
        // 获取选定的多个行数据
        List<Student> selectedStudents = new ArrayList<>
                (studentTableView.getSelectionModel().getSelectedItems());
        // 使用系统确认框询问
        Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
        alert.setHeaderText("您确定要删除选定的学生信息吗？");
        // 显示对话框，并等待按钮返回
        Optional<ButtonType> result = alert.showAndWait();
        // 判断返回的按钮类型是确定还是取消，再据此分别进一步处理
        if (result.get() == ButtonType.OK) {
            try {
                // 删除选定的学生信息
                deleteSelectedStudents(selectedStudents);
                //刷新数据表格
                refreshTableView();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

    // 添加编辑按钮事件
    @FXML
    private void btnEdit(ActionEvent actionEvent) {
        // 获取选定的单个行数据
        Student selectedStudent = studentTableView.getSelectionModel().getSelectedItem();

        if (selectedStudent != null) {
            // 创建编辑对话框，将选中学生的图片路径传递给对话框
            Dialog<Student> dialog = createEditStudentDialog(selectedStudent);
            Optional<Student> result = dialog.showAndWait();

            // 处理编辑结果
            result.ifPresent(updatedStudent -> {
                try (Connection connection = DruidUtil.getConnection()) {
                    StudentDaoImpl studentDao = new StudentDaoImpl(connection);
                    studentDao.updateByPrimaryKey(updatedStudent);
                    // 刷新数据表格
                    refreshTableView();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            });
        }
    }

    // 创建编辑学生信息的对话框，增加 photoPath 参数
    private Dialog<Student> createEditStudentDialog(Student student) {
        Dialog<Student> dialog = new Dialog<>();
        dialog.setTitle("编辑学生信息");
        dialog.setHeaderText("编辑学生信息");

        // 设置按钮
        ButtonType saveButtonType = new ButtonType("保存", ButtonBar.ButtonData.OK_DONE);
        dialog.getDialogPane().getButtonTypes().addAll(saveButtonType, ButtonType.CANCEL);

        // 设置布局
        GridPane editGrid = new GridPane();
        editGrid.setHgap(10);
        editGrid.setVgap(10);
        editGrid.setPadding(new Insets(20, 150, 10, 10));

        // 在网格面板中添加编辑输入框
        TextField snoField = new TextField();
        snoField.setText(student.getSno());
        snoField.setEditable(false);  // 设置为不可编辑
        TextField nameField = new TextField(student.getName());
        TextField ageField = new TextField(student.getAge());
        TextField sexField = new TextField(student.getSex());
        TextField telField = new TextField(student.getTel());

        editGrid.add(new Label("学号:"), 0, 0);
        editGrid.add(snoField, 1, 0);
        editGrid.add(new Label("姓名:"), 0, 1);
        editGrid.add(nameField, 1, 1);
        editGrid.add(new Label("年龄:"), 0, 2);
        editGrid.add(ageField, 1, 2);
        editGrid.add(new Label("性别:"), 0, 3);
        editGrid.add(sexField, 1, 3);
        editGrid.add(new Label("手机号码:"), 0, 4);
        editGrid.add(telField, 1, 4);

        // 添加显示图片的 ImageView
        ImageView imageView = new ImageView(new Image(getClass().getResourceAsStream("/com/example/week14/photo/" + student.getPhoto())));
        imageView.setFitWidth(48);
        imageView.setFitHeight(48);
        editGrid.add(new Label("照片:"), 0, 5);
        editGrid.add(imageView, 1, 5);

        dialog.getDialogPane().setContent(editGrid);

        // 设置对话框的结果转换器
        dialog.setResultConverter(dialogButton -> {
            if (dialogButton == saveButtonType) {
                return new Student(
                        snoField.getText(),
                        nameField.getText(),
                        ageField.getText(),
                        sexField.getText(),
                        telField.getText(),
                        student.getPhoto() // 保持原图片路径
                );
            }
            return null;
        });

        return dialog;
    }

    //添加学生信息
    @FXML
    private void addStudent(ActionEvent actionEvent) {

        // 获取输入框的值
        String studentId = inputStudentId.getText();
        String studentName = inputStudentName.getText();
        String studentAge = inputStudentAge.getText();
        String studentSex = maleToggleButton.isSelected() ? "男" : "女";
        String studentTel = inputStudentTel.getText();

        // 验证输入是否有效
        if (validateInput(studentId, studentName, studentAge, studentTel)) {
            try (Connection connection = DruidUtil.getConnection()) {
                // 创建学生数据访问对象
                StudentDaoImpl studentDao = new StudentDaoImpl(connection);

                // 检查学号是否重复
                if (!studentDao.isStudentIdExists(studentId)) {
                    // 学号不重复，创建新的学生对象，默认照片路径为 "photo1.jpg"
                    Student newStudent = new Student(studentId, studentName, studentAge, studentSex, studentTel, "photo1.jpg");

                    // 插入新学生信息
                    studentDao.insert(newStudent);

                    // 刷新数据表格
                    refreshTableView();
                } else {
                    // 学号重复，弹出警告框
                    Alert alert = new Alert(Alert.AlertType.WARNING);
                    alert.setHeaderText("学号重复");
                    alert.setContentText("请重新输入学号!");
                    alert.showAndWait();
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } else {
            // 弹出警告框，输入无效
            Alert alert = new Alert(Alert.AlertType.WARNING);
            alert.setHeaderText("输入无效");
            alert.setContentText("必须填写学号!");
            alert.showAndWait();
        }
    }

    // 验证输入是否有效
    private boolean validateInput(String studentId, String studentName, String studentAge, String studentTel) {
        return !studentId.isEmpty() && !studentName.isEmpty() && !studentAge.isEmpty() && !studentTel.isEmpty();
    }

    @FXML
    private void queryStudents(ActionEvent actionEvent) {
        // 获取查询条件的值
        String studentId = inputStudentId.getText();
        String studentName = inputStudentName.getText();
        String studentAge = inputStudentAge.getText();
        String studentSex = maleToggleButton.isSelected() ? "男" : (femaleToggleButton.isSelected() ? "女" : "");
        String studentTel = inputStudentTel.getText();

        try (Connection connection = DruidUtil.getConnection()) {
            // 创建学生数据访问对象
            StudentDaoImpl studentDao = new StudentDaoImpl(connection);

            // 执行查询
            List<Student> studentList = studentDao.queryStudents(studentId, studentName, studentAge, studentSex, studentTel);

            // 更新表格数据
            studentTableView.getItems().clear();
            studentTableView.getItems().addAll(studentList);

            // 更新查询结果数量
            resultCountLabel.setText("共查询到 " + studentList.size() + " 条记录。");
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}
